[CODE BLUE 2017]インサイドShell:.NETハッキング技術を応用したPowerShell可視性の向上 丹田 賢 – Satoshi Tanda -[レポート] #codeblue_jp #codeblue_jp_t1
こんにちは、臼田です。
『世界トップクラスのセキュリティ専門家による日本発の情報セキュリティ国際会議』でありますCODE BLUE 2017に参加していますのでレポートします。
このブログは下記セッションについてのレポートです。
インサイドShell:.NETハッキング技術を応用したPowerShell可視性の向上 - 丹田 賢 - Satoshi Tanda -
レポート
Powershell攻撃への対応の難しさとAMSI
- PowerShellは攻撃の中で頻繁に利用されている
- AVソフトウェアでの検知が難しい
- プロセス(powershell.exe)はデジタル署名された正当なファイル
- スクリプトファイルは簡単に変更できる
- スクリプトファイルは使用されないかもしれない
- PowerShellエンジンは任意のプロセスに読み込まれ、そこで動作しうる(PSInject)
- 実際には更に難しい
- AVがテキストファイルをスキャンしない可能性がある
- iexでストリングをダウンロードして実行すると静的には何が起こるかわからない
- エンコードされたテキストにより難読化
- AMSI
- Windows10でリリース
- AMSIプロバイダーとしてソフトウェアを登録(MSとNDAが必要)
- 銀の弾丸(のように見える)
- スクリプトファイルの内容がわかる
- Invoke-Expressionされた文字列の内容がわかる
- デコードされた後のコマンド文字列が分かる
- PowerShellエンジンが使用される場合常に有効
- しかし制約もある
- AMSIはPowerShell v5 + Windows10のみ有効
- 一部の難読化されたPowerShellは難読化されたまま
- AMSIはPowerShellから無効化されうる(管理者権限不要)
- AMSIプロバイダーが正しいデータを受け取れない問題(現在未修正)
- おさらい
- PowerShellベースの攻撃は一般的、しかし検出が困難
- AMSIは非常に有用、しかし制限がある
- 何ができないか? -> 答えはイエス
.NETネイティブコードフックの紹介
- ネイティブコードフック
- 生成されたネイティブコードを書き換えることによってマネージドプログラムの動作を実行時に変更する技術
- プログラムの動作の監視や変更を可能とする
- マネージドプログラム実行の基礎
- C#のようなコンパイル言語で書かれたプログラムはMSILにコンパイルされる
- MSILは2種類の方法によりコンパイルされる
- いずれの場合もネイティブコードが実行される
- マネージドプログラムはAPIを提供する.NET Framwork上で実行される
- フックを.NET Frameworkもしくはマネージドプログラムに入れる
- フックの概略
- アンマネージドコードのフックの典型的な流れと.NETネイティブコードのフックは同様、ただし.NEETアセンブリとメソッドを対象とする
- どうやってアドレスを特定するか
- リフレクションによりマネージドプログラムは.NETアセンブリやメソッド、フィールドなどの情報を実行時に取得
- 生成されたネイティブコードのアドレスを得る
- 対象関数が実行されていない場合にはネイティブコードは存在しないかもしれない
- Preparemethodを利用
- どうやってフックするコードを実行するか
- フックをインストールするために対象プロセス内でマネージドコードを実行する必要がある
- Hosting APIを利用する
- アンマネージドの仕様
- bootstrapをインジェクト
- フック用.NETアセンブリをbootsttapコードからインジェクト
- ネイティブコードを上書き
- USING APPDOMAINMANAGERの使用
- 独自のAppDomainManagerを実装
- 最初にAppDomainが作られる時にCLRが登録されたフック用絵アセンブリを読み込み実行
- ネイティブコードを上書き
- 利点: 最小のコード
- 欠点: 環境変数等の事前設定が必要
Powershellに対する可視性の向上
- PowerShellはマネージドプログラム
- C#で書かれている
- Powershell.exeはSMA.dllのクライアントにすぎない
- SMA.dllの動作をフックして監視できる
- AMSI拡張など
- AMSIと同様の機能をWindows8.1以前に実装
- PowerShell以外に実装
- AMSIバイパスを無効
- 文字列の難読化を解除
- コマンドレットをフック
- AMSIエミュレーション: 古いWindows + PSv5
- SMA.dllのメソッドをフックしてエミュレーション
- AmsiUtils.ScanContentメソッドを独自のスキャンロジックで上書き
- AMSIエミュレーション: 古いPS
- 困難
- AmsiUtilsクラスは存在しない
- オープンソースもない
- リバースエンジニアリングを通して適切なメソッドを見つける必要がある
- Good News ;-)
- 無料の.NETコンパイラが存在、読みやすいコードを生成
- デバッガはソースがあるかのように動作する
- 多くの実装はオープンソース版のそれに近い
- 困難
- AMSIバイパスの無効化
- 既知のバイパスはScanContentメソッドからのAmsiScanString関数呼び出しか、適切なAMSIプロバイダーDLLの利用をする
- コマンドレットの実行
- 難読化が解除された状態のパラメータにアクセス可能
- コマンドレットが実行されるときProcessRecordメソッドが呼び出される
- thisポインターが全パラメータを保持
- デモ
- フックベースの動作も確認できる
- AMSIを無効化しようとすると、AMSIプロバイダーは出力がなくなってしまう
- フックベースの方は引き続き確認できる
- PSのV2を指定して実行するランサムウェアを元にしたコードを実行すると、AMSIは動かない
- フックベースはきちんとファイルのダウンロードや保存が確認できる
- 難読化コードについてもフックベースで内容が確認できる
- 困難と制限
- リバースエンジニアリングと実装依存のコードが必要
- 低レベルのメソッドをフックした場合、出力が多すぎる可能性
- 攻撃者は同様のテクニックによりフックをバイパス可能
まとめと提言
- AMSIは有用だが制限もある
- .NETネイティブコードフックによりマネージドプログラムの動作を関し・変更できる
- AMSIと同様の機能を古いバージョンのWindowsはPS上で実装できる
- 更に拡張した機能を実装できる
- セキュリティプロフェッショナル向け
- Windows 10 + PSv5を使用し、セキュリティ機能を理解する
- Constrained Language Mode と AppLocker または Device Guardを導入する
- PSv2の削除
- システムを最新に保つ
- 研究者/セキュリティソフトウェアをベンダー向け
- AMSIの機能を理解する
- .NETネイティブコードフックが利用可能か評価する
- サンプルコードを見てみる
- GetFunctionPointerの利用に注意する
- 攻撃者によって利用される可能性がある
感想
AMSIがとてもいいセキュリティ機能であることを理解すると同時に、課題についてもよく理解できました
システムを最新に保つことを忘れず、メーカにはより良い対策の実装に期待したいですね